/*
==================================================================
* 版权所有 © 2025 CaryXiong
* Copyright (C) 2025 CaryXiong(a1816101108@outlook.com)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
===================================================================
*/


/*
对于多维数组的构造函数和析构函数（即数组的初始化和内存销毁）参考 @雪山上的小草 的以下文章：
https://blog.csdn.net/m0_37154839/article/details/85335218
如有侵权，请联系删除！
*/



#include<iostream>
using namespace std;

template<class DataType>
class TwoDimen_Array{
    public:
        TwoDimen_Array(DataType *data, int row, int column);
        TwoDimen_Array(int row, int column);
        ~TwoDimen_Array();
        DataType GetValue(int i, int j);
        void SetValue(DataType x, int i, int j);
        void TransArray();
        DataType FindMax();
        DataType FindMin();
        DataType GetAverage();
        void caculArray();

    private:
        DataType **data, **TransResult, **caculResult;
        DataType average;
        int row, column;
};


template<class DataType>
TwoDimen_Array<DataType> :: TwoDimen_Array(DataType *data, int row, int column){
    this->row = row; this->column = column;
    this->data = new DataType*[row];
    for(int i=0; i<row; i++){
        this->data[i] = new DataType[column];
    }

    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++){
            this->data[i][j] = *((int*)data + row*i + j);
        }
    }
}

template<class DataType>
TwoDimen_Array<DataType> :: TwoDimen_Array(int row, int column){
    this->row = row; this->column = column;
    this->data = new DataType*[row];
    for(int i=0; i<row; i++){
        this->data[i] = new DataType[column];
    }
}

template<class DataType>
TwoDimen_Array<DataType> :: ~TwoDimen_Array(){
    for (int i = 0; i < row; i++) {
        delete[] data[i];
    }
    delete[] data;
}

template<class DataType>
DataType TwoDimen_Array<DataType> :: GetValue(int i, int j){
    return data[i-1][j-1];
}

template<class DataType>
void TwoDimen_Array<DataType> :: SetValue(DataType x, int i, int j){
    data[i-1][j-1] = x;
}

template<class DataType>
void TwoDimen_Array<DataType> :: TransArray(){
    TransResult = new DataType*[column];
    for(int i=0; i<column; i++){
        TransResult[i] = new DataType[row];
    }

    for(int i=0; i<column; i++){
        for(int j=0; j<row; j++){
            TransResult[i][j] = data[j][i];
        }
    }

    for(int i=0; i<column; i++){
        for(int j=0; j<row; j++){
            cout << TransResult[i][j] << '\t';
        }
        cout << endl;
    }
}

template<class DataType>
DataType TwoDimen_Array<DataType> :: FindMax(){
    DataType max = data[0][0];
    int rowPos=1, columnPos=1;
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++){
            if(data[i][j] > max){
                max = data[i][j];
                rowPos = i+1;
                columnPos = j+1;
            }
        }
    }
    cout << "最大值为" << max << ", 位于坐标(" << rowPos << ',' << columnPos << ")处" << endl;
    return max;
}

template<class DataType>
DataType TwoDimen_Array<DataType> :: FindMin(){
    DataType min = data[0][0];
    int rowPos=1, columnPos=1;
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++){
            if(data[i][j] < min){
                min = data[i][j];
                rowPos = i+1;
                columnPos = j+1;
            }
        }
    }
    cout << "最小值为" << min << ", 位于坐标(" << rowPos << ',' << columnPos << ")处" << endl;
    return min;
}

template<class DataType>
DataType TwoDimen_Array<DataType> :: GetAverage(){
    average = 0;
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++){
            average += data[i][j];
        }
    }
    average /= (row*column);
    return average;
}

template<class DataType>
void TwoDimen_Array<DataType> :: caculArray(){
    caculResult = new DataType*[row];
    for(int i=0; i<row; i++){
        caculResult[i] = new DataType[column];
    }

    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++){
            caculResult[i][j] = data[i][j] - average;
        }
    }


    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++){
            cout << caculResult[i][j] << '\t';
        }
        cout << endl;
    }
}



int main(){
    int a[3][3] = {
        {1,2,3},
        {4,5,6},
        {7,8,9}
    };
    TwoDimen_Array<int> A((int*)a,3,3);

    cout << "当前矩阵为：" << endl;
    for(int i=0; i<3; i++){
        for(int j=0; j<3; j++){
            cout << a[i][j] << '\t';
        }
        cout << endl;
    }

    cout << "转置该矩阵，结果为：" << endl;
    A.TransArray();
    cout << endl;

    A.FindMax();
    A.FindMin();
    cout << "该矩阵的所有元素平均值为：" << A.GetAverage() << endl << endl;

    cout << "根据该矩阵求出对应的b矩阵如下：" << endl;
    A.caculArray();

    int test;
    cin >> test;
}